﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

using Alicanto.Helpers;
using Alicanto.Execution;
using Alicanto.Api;

namespace Alicanto.Compilation.Code.Operators.Assignment
{
    internal class OpAssign : ICodeGenerator
    {
        public Expression Code { get; private set; }

        public IEnumerable<ParseInstruction> Generate(TokenSequence tokens, Scope scope)
        {
            GetEvaluation evaluation = new GetEvaluation();
            yield return evaluation;

            ParseExpression expression = new ParseExpression();
            yield return expression;

            Expression x = evaluation.Expression;
            Expression y = expression.Expression;

            // Assignment
            if (evaluation.Expression.Type != typeof(void))
            {
                y = Boxing.EnsureBox(y, x.Type);

                this.Code = Expression.Assign(
                    x,
                    y
                );
            }
            // Print
            else
            {
                this.Code = Expression.Call(
                    null,
                    typeof(Globals).GetMethod(
                        "print",
                        new Type[] {
                            typeof(ExecutionContext),
                            typeof(object)
                        }
                    ),
                    Expression.Constant(scope.ExecutionContext),
                    Conversion.Ensure(y, typeof(object))
                );
            }
        }
    }
}
